﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Windows.Forms;
using ChainAnalises.Classes.DataMining;
using ChainAnalises.Classes.DivizionToAccords.Criteria;
using ChainAnalises.Classes.IntervalAnalysis;
using ChainAnalises.Classes.IntervalAnalysis.Characteristics;
using ChainAnalises.Classes.Project_A;
using ChainAnalises.Classes.Root.SimpleTypes;
using ChainAnalises.Classes.TheoryOfSet;
using MarkovCompare.Excel;
using Segmentator.Dividers;
using Segmentator.IntegrityThroughInterval;
using Segmentator.Interfaces;
using Segmentator.Micro;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;



namespace Segmentator
{
    public partial class Form1 : Form, IDataLoader, IDataUploader
    {
        private DateTime start_time;
        #region //Интерфейс IDataUploader
        /// <summary>
        /// Энтропия просегментированной цепи
        /// </summary>
        /// <param name="value">Значение</param>
        public void OutEntropy(double value)
        {
            H2.Text = Convert.ToString(value);
        }
        /// <summary>
        /// Количество информации просегментированной цепи
        /// </summary>
        /// <param name="value">Значение</param>
        public void OutAmountOfInformation(double value)
        {
            Hn2.Text = Convert.ToString(value);
        }
        /// <summary>
        /// Удаленность просегментированной цепи цепи
        /// </summary>
        /// <param name="value">Значение</param>
        public void OutChainRemoteness(double value)
        {
            g2.Text = Convert.ToString(value);
        }
        /// <summary>
        /// Регулярность просегментированной цепи
        /// </summary>
        /// <param name="value">Значение</param>
        public void OutChainRegularity(double value)
        {
            r2.Text = Convert.ToString(value);
        }
        /// <summary>
        /// Глубина просегментированной цепи
        /// </summary>
        /// <param name="value">Значение</param>
        public void OutChainGamut(double value)
        {
            Gg2.Text = Convert.ToString(value);
        }

        /// <summary>
        /// Теоритический объем алфавита просегментированной цепи
        /// </summary>
        /// <param name="value">Значение</param>
        public void OutTheoryVolumeOfAlphabet(double value)
        {
            pTheor.Text = Convert.ToString(value);
        }
        /// <summary>
        /// Практический объем алфавита просегментированной цепи
        /// </summary>
        /// <param name="value"></param>
        public void OutEmpiricalVolumeOfAlphabet(double value)
        {
            pPract.Text = Convert.ToString(value);
        }
        /// <summary>
        /// Энтропия исходной цепи
        /// </summary>
        /// <param name="value">Значение</param>
        public void InEntropy(double value)
        {
            H1.Text = Convert.ToString(value);
        }
        /// <summary>
        /// Количество информации исходной цепи
        /// </summary>
        /// <param name="value">Значение</param>
        public void InAmountOfInformation(double value)
        {
            Hn1.Text = Convert.ToString(value);
        }
        /// <summary>
        /// Удаленность исходной цепи
        /// </summary>
        /// <param name="value">Значение</param>
        public void InChainRemoteness(double value)
        {
            g1.Text = Convert.ToString(value);
        }
        /// <summary>
        /// Регулярность исходной цепи
        /// </summary>
        /// <param name="value">Значение</param>
        public void InChainRegularity(double value)
        {
            r1.Text = Convert.ToString(value);
        }
        /// <summary>
        /// Глубина исходной цепи
        /// </summary>
        /// <param name="value">Значение</param>
        public void InChainGamut(double value)
        {
            Gg1.Text = Convert.ToString(value);
        }
        /// <summary>
        /// Просегментированная цепь
        /// </summary>
        /// <param name="chain">Значение</param>
        public void OutSlotChain(string chain)
        {
            segmentatedChain.Text = chain;
        }

        public void OutFormationSlotChain(string formation)
        {
            segmentayedChainBuilding.Text = formation;
        }

        public void OutFoundThreshold(double value)
        {
            Threshold.Text = Convert.ToString(value);
        }

        public void OutDictionary(List<string> dictionary)
        {
            for (int i = 0; i < dictionary.Count; i++)
            {
                cboutAlpha.Items.Add(dictionary[i]);
            }
           
        }

        /// <summary>
        /// Строй просегментированной цепи
        /// </summary>
        /// <param name="formation">Значение</param>
        public void FormationSlotChain(string formation)
        {
            segmentayedChainBuilding.Text = formation;
        }
        /// <summary>
        /// Строй исходной цепи
        /// </summary>
        /// <param name="formation"></param>
        public void InFormationChain(string formation)
        {
            chainToSegmentationBuilding.Text = formation;
        }

        #endregion // Инт

        public Form1()
        {
            InitializeComponent();
            CrossAlpha = new AlphabetComparer();
            ThresholdChooser.Items.Add(RandomThreshold.Name);
            ThresholdChooser.Items.Add(LinerThreshold.Name);
            ThresholdChooser.Items.Add(DichotomyThreshold.Name);
            start_time = DateTime.Now;
        }

        private void button4_Click_1(object sender, EventArgs e)
        {
            Algorithm segmentator = null;
            CalculatorResults results = null;

            if (radioButton1.Checked) segmentator = new GurovRodionov();
                else segmentator = new OrlovPartialCriterion();

            segmentator.LoadData(this);
            segmentator.Slot();
            results = segmentator.UpLoadData();

            BaseCharacteristic baseCharacteristic = new BaseCharacteristic(results);
            Device output1 = new OutExcelDevice(this);
            Device output2 = new OutFormDevice();

            output1.Print(baseCharacteristic.Format(this), this);
            output2.Print(baseCharacteristic.Format(this), this);

            EndTime();
        }

 
        private void EndTime()
        {
            TimeSpan dif = DateTime.Now - this.start_time;
            Time.Text = dif.TotalDays.ToString() + ":" + dif.Hours.ToString() + ":"+ dif.Minutes.ToString() + ":" + dif.Seconds.ToString();
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (CountIter.Visible)
            {
                CountIter.Visible = false;
                lcountStr.Visible = false;
            }
            else if (!CountIter.Visible)
            {
                CountIter.Visible = true;
                lcountStr.Visible = true;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            CrossAlpha.MultyLoad();
            ValidAlpha.Items.Clear();
            ValidAlpha.Items.AddRange(CrossAlpha.GetDividerNames().ToArray());
        }

        public byte[] ConverDataToByteArray(Alphabet dataClass)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            formatter.Serialize(stream, dataClass);
            return stream.ToArray();
        }

        public Chain ConverByteArreyToData(byte[] binaryData)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream ms = new MemoryStream(binaryData);
            return (Chain)formatter.Deserialize(ms);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            String compoundName = null;
            ExcelDevice excel = new ExcelDevice();

            CrossAlpha.Compare();

            foreach (String s in ValidAlpha.Items) compoundName += s+"_";
            
            excel.NewDocument();
            excel.SetColunOfValues(CrossAlpha.toStringArray(), "Словарь склеек", 4);
            if (File.Exists(Application.StartupPath + "\\Serializations\\Cross_" + compoundName + ".xls")) File.Delete(Application.StartupPath + "\\Serializations\\Cross_" + compoundName + ".xls");
            excel.SaveDocument(Application.StartupPath + "\\Serializations\\Cross_" + compoundName + ".xls");
            excel.CloseDocument();
        }

        private void chainToSegmentation_TextChanged(object sender, EventArgs e)
        {
            dnaLen.Text = chainToSegmentation.Text.Length.ToString();
        }
        #region //Интерфейс IDataLoader
        public double GetThresholdLeft()
        {
            return Convert.ToDouble(leftBound.Text);
        }

        public double GetThresholdRight()
        {
            return Convert.ToDouble(rightBound.Text); ;
        }

        public double GetThresholdStep()
        {
            return Convert.ToDouble(StepThreshold.Text);
        }

        public double GetBalanceFactor()
        {
            return (float) balance.Value;
        }

        public int GetLengthStartWindow()
        {
            return (int) length.Value;
        }

        public double GetPrecision()
        {
            return float.Parse(Epst.Text);
        }

        public int GetAmountStartAlgorithm()
        {
            return (int)CountIter.Value;
        }

        public bool IsSavingResults()
        {
            return cbSerialization.Checked;
        }

        public string GetChainName()
        {
            return DNA.Text;
        }

        public string GetSequence()
        {
           return chainToSegmentation.Text.ToUpper();
        }

        public double GetMinAlphabetsDistortion()
        {
            return Convert.ToDouble(Distortion.Text);
        }
        #endregion

    }
}
